"""A script for collecting and generating files for bison BUILD files."""

import argparse
import shutil
import os
import re
import platform
import json
from pathlib import Path

TEMPLATE_KEYS = [
    "APPLE_UNIVERSAL_BUILD",
    "ASM_SYMBOL_PREFIX",
    "BITSIZEOF_PTRDIFF_T",
    "BITSIZEOF_SIG_ATOMIC_T",
    "BITSIZEOF_SIZE_T",
    "BITSIZEOF_WCHAR_T",
    "BITSIZEOF_WINT_T",
    "EMULTIHOP_HIDDEN",
    "EMULTIHOP_VALUE",
    "ENOLINK_HIDDEN",
    "ENOLINK_VALUE",
    "EOVERFLOW_HIDDEN",
    "EOVERFLOW_VALUE",
    "GNULIBHEADERS_OVERRIDE_WINT_T",
    "GNULIB_ACCESS",
    "GNULIB_ACOSF",
    "GNULIB_ACOSL",
    "GNULIB_ALIGNED_ALLOC",
    "GNULIB_ALPHASORT",
    "GNULIB_ASINF",
    "GNULIB_ASINL",
    "GNULIB_ATAN2F",
    "GNULIB_ATANF",
    "GNULIB_ATANL",
    "GNULIB_ATOLL",
    "GNULIB_BTOWC",
    "GNULIB_CALLOC_POSIX",
    "GNULIB_CANONICALIZE_FILE_NAME",
    "GNULIB_CBRT",
    "GNULIB_CBRTF",
    "GNULIB_CBRTL",
    "GNULIB_CEIL",
    "GNULIB_CEILF",
    "GNULIB_CEILL",
    "GNULIB_CHDIR",
    "GNULIB_CHOWN",
    "GNULIB_CLOSE",
    "GNULIB_CLOSEDIR",
    "GNULIB_COPYSIGN",
    "GNULIB_COPYSIGNF",
    "GNULIB_COPYSIGNL",
    "GNULIB_COPY_FILE_RANGE",
    "GNULIB_COSF",
    "GNULIB_COSHF",
    "GNULIB_COSL",
    "GNULIB_CREAT",
    "GNULIB_CTIME",
    "GNULIB_DIRFD",
    "GNULIB_DPRINTF",
    "GNULIB_DUP2",
    "GNULIB_DUP3",
    "GNULIB_DUP",
    "GNULIB_DUPLOCALE",
    "GNULIB_ENVIRON",
    "GNULIB_EUIDACCESS",
    "GNULIB_EXECL",
    "GNULIB_EXECLE",
    "GNULIB_EXECLP",
    "GNULIB_EXECV",
    "GNULIB_EXECVE",
    "GNULIB_EXECVP",
    "GNULIB_EXECVPE",
    "GNULIB_EXP2",
    "GNULIB_EXP2F",
    "GNULIB_EXP2L",
    "GNULIB_EXPF",
    "GNULIB_EXPL",
    "GNULIB_EXPLICIT_BZERO",
    "GNULIB_EXPM1",
    "GNULIB_EXPM1F",
    "GNULIB_EXPM1L",
    "GNULIB_FABSF",
    "GNULIB_FABSL",
    "GNULIB_FACCESSAT",
    "GNULIB_FCHDIR",
    "GNULIB_FCHMODAT",
    "GNULIB_FCHOWNAT",
    "GNULIB_FCLOSE",
    "GNULIB_FCNTL",
    "GNULIB_FDATASYNC",
    "GNULIB_FDOPEN",
    "GNULIB_FDOPENDIR",
    "GNULIB_FFLUSH",
    "GNULIB_FFS",
    "GNULIB_FFSL",
    "GNULIB_FFSLL",
    "GNULIB_FGETC",
    "GNULIB_FGETS",
    "GNULIB_FLOOR",
    "GNULIB_FLOORF",
    "GNULIB_FLOORL",
    "GNULIB_FMA",
    "GNULIB_FMAF",
    "GNULIB_FMAL",
    "GNULIB_FMOD",
    "GNULIB_FMODF",
    "GNULIB_FMODL",
    "GNULIB_FOPEN",
    "GNULIB_FPRINTF",
    "GNULIB_FPRINTF_POSIX",
    "GNULIB_FPURGE",
    "GNULIB_FPUTC",
    "GNULIB_FPUTS",
    "GNULIB_FREAD",
    "GNULIB_FREELOCALE",
    "GNULIB_FREE_POSIX",
    "GNULIB_FREOPEN",
    "GNULIB_FREXP",
    "GNULIB_FREXPF",
    "GNULIB_FREXPL",
    "GNULIB_FSCANF",
    "GNULIB_FSEEK",
    "GNULIB_FSEEKO",
    "GNULIB_FSTAT",
    "GNULIB_FSTATAT",
    "GNULIB_FSYNC",
    "GNULIB_FTELL",
    "GNULIB_FTELLO",
    "GNULIB_FTRUNCATE",
    "GNULIB_FUTIMENS",
    "GNULIB_FWRITE",
    "GNULIB_GETC",
    "GNULIB_GETCHAR",
    "GNULIB_GETCWD",
    "GNULIB_GETDELIM",
    "GNULIB_GETDOMAINNAME",
    "GNULIB_GETDTABLESIZE",
    "GNULIB_GETENTROPY",
    "GNULIB_GETGROUPS",
    "GNULIB_GETHOSTNAME",
    "GNULIB_GETLINE",
    "GNULIB_GETLOADAVG",
    "GNULIB_GETLOGIN",
    "GNULIB_GETLOGIN_R",
    "GNULIB_GETOPT_POSIX",
    "GNULIB_GETPAGESIZE",
    "GNULIB_GETPASS",
    "GNULIB_GETRUSAGE",
    "GNULIB_GETSUBOPT",
    "GNULIB_GETTIMEOFDAY",
    "GNULIB_GETUMASK",
    "GNULIB_GETUSERSHELL",
    "GNULIB_GRANTPT",
    "GNULIB_GROUP_MEMBER",
    "GNULIB_HYPOT",
    "GNULIB_HYPOTF",
    "GNULIB_HYPOTL",
    "GNULIB_ICONV",
    "GNULIB_ILOGB",
    "GNULIB_ILOGBF",
    "GNULIB_ILOGBL",
    "GNULIB_IMAXABS",
    "GNULIB_IMAXDIV",
    "GNULIB_IOCTL",
    "GNULIB_ISATTY",
    "GNULIB_ISFINITE",
    "GNULIB_ISINF",
    "GNULIB_ISNAN",
    "GNULIB_ISNAND",
    "GNULIB_ISNANF",
    "GNULIB_ISNANL",
    "GNULIB_ISWBLANK",
    "GNULIB_ISWCTYPE",
    "GNULIB_ISWDIGIT",
    "GNULIB_ISWXDIGIT",
    "GNULIB_LCHMOD",
    "GNULIB_LCHOWN",
    "GNULIB_LDEXPF",
    "GNULIB_LDEXPL",
    "GNULIB_LINK",
    "GNULIB_LINKAT",
    "GNULIB_LOCALECONV",
    "GNULIB_LOCALENAME",
    "GNULIB_LOCALTIME",
    "GNULIB_LOG10",
    "GNULIB_LOG10F",
    "GNULIB_LOG10L",
    "GNULIB_LOG1P",
    "GNULIB_LOG1PF",
    "GNULIB_LOG1PL",
    "GNULIB_LOG2",
    "GNULIB_LOG2F",
    "GNULIB_LOG2L",
    "GNULIB_LOG",
    "GNULIB_LOGB",
    "GNULIB_LOGBF",
    "GNULIB_LOGBL",
    "GNULIB_LOGF",
    "GNULIB_LOGL",
    "GNULIB_LSEEK",
    "GNULIB_LSTAT",
    "GNULIB_MALLOC_POSIX",
    "GNULIB_MBRLEN",
    "GNULIB_MBRTOWC",
    "GNULIB_MBSCASECMP",
    "GNULIB_MBSCASESTR",
    "GNULIB_MBSCHR",
    "GNULIB_MBSCSPN",
    "GNULIB_MBSINIT",
    "GNULIB_MBSLEN",
    "GNULIB_MBSNCASECMP",
    "GNULIB_MBSNLEN",
    "GNULIB_MBSNRTOWCS",
    "GNULIB_MBSPBRK",
    "GNULIB_MBSPCASECMP",
    "GNULIB_MBSRCHR",
    "GNULIB_MBSRTOWCS",
    "GNULIB_MBSSEP",
    "GNULIB_MBSSPN",
    "GNULIB_MBSSTR",
    "GNULIB_MBSTOK_R",
    "GNULIB_MBTOWC",
    "GNULIB_MDA_ACCESS",
    "GNULIB_MDA_CHDIR",
    "GNULIB_MDA_CHMOD",
    "GNULIB_MDA_CLOSE",
    "GNULIB_MDA_CREAT",
    "GNULIB_MDA_DUP2",
    "GNULIB_MDA_DUP",
    "GNULIB_MDA_ECVT",
    "GNULIB_MDA_EXECL",
    "GNULIB_MDA_EXECLE",
    "GNULIB_MDA_EXECLP",
    "GNULIB_MDA_EXECV",
    "GNULIB_MDA_EXECVE",
    "GNULIB_MDA_EXECVP",
    "GNULIB_MDA_EXECVPE",
    "GNULIB_MDA_FCLOSEALL",
    "GNULIB_MDA_FCVT",
    "GNULIB_MDA_FDOPEN",
    "GNULIB_MDA_FILENO",
    "GNULIB_MDA_GCVT",
    "GNULIB_MDA_GETCWD",
    "GNULIB_MDA_GETPID",
    "GNULIB_MDA_GETW",
    "GNULIB_MDA_ISATTY",
    "GNULIB_MDA_J0",
    "GNULIB_MDA_J1",
    "GNULIB_MDA_JN",
    "GNULIB_MDA_LSEEK",
    "GNULIB_MDA_MEMCCPY",
    "GNULIB_MDA_MKDIR",
    "GNULIB_MDA_MKTEMP",
    "GNULIB_MDA_OPEN",
    "GNULIB_MDA_PUTENV",
    "GNULIB_MDA_PUTW",
    "GNULIB_MDA_READ",
    "GNULIB_MDA_RMDIR",
    "GNULIB_MDA_STRDUP",
    "GNULIB_MDA_SWAB",
    "GNULIB_MDA_TEMPNAM",
    "GNULIB_MDA_TZSET",
    "GNULIB_MDA_UMASK",
    "GNULIB_MDA_UNLINK",
    "GNULIB_MDA_WCSDUP",
    "GNULIB_MDA_WRITE",
    "GNULIB_MDA_Y0",
    "GNULIB_MDA_Y1",
    "GNULIB_MDA_YN",
    "GNULIB_MEMCHR",
    "GNULIB_MEMMEM",
    "GNULIB_MEMPCPY",
    "GNULIB_MEMRCHR",
    "GNULIB_MKDIR",
    "GNULIB_MKDIRAT",
    "GNULIB_MKDTEMP",
    "GNULIB_MKFIFO",
    "GNULIB_MKFIFOAT",
    "GNULIB_MKNOD",
    "GNULIB_MKNODAT",
    "GNULIB_MKOSTEMP",
    "GNULIB_MKOSTEMPS",
    "GNULIB_MKSTEMP",
    "GNULIB_MKSTEMPS",
    "GNULIB_MKTIME",
    "GNULIB_MODF",
    "GNULIB_MODFF",
    "GNULIB_MODFL",
    "GNULIB_NANOSLEEP",
    "GNULIB_NEWLOCALE",
    "GNULIB_NONBLOCKING",
    "GNULIB_OBSTACK_PRINTF",
    "GNULIB_OBSTACK_PRINTF_POSIX",
    "GNULIB_OPEN",
    "GNULIB_OPENAT",
    "GNULIB_OPENDIR",
    "GNULIB_OVERRIDES_STRUCT_STAT",
    "GNULIB_PCLOSE",
    "GNULIB_PERROR",
    "GNULIB_PIPE2",
    "GNULIB_PIPE",
    "GNULIB_POPEN",
    "GNULIB_POSIX_MEMALIGN",
    "GNULIB_POSIX_OPENPT",
    "GNULIB_POSIX_SPAWN",
    "GNULIB_POSIX_SPAWNATTR_DESTROY",
    "GNULIB_POSIX_SPAWNATTR_GETFLAGS",
    "GNULIB_POSIX_SPAWNATTR_GETPGROUP",
    "GNULIB_POSIX_SPAWNATTR_GETSCHEDPARAM",
    "GNULIB_POSIX_SPAWNATTR_GETSCHEDPOLICY",
    "GNULIB_POSIX_SPAWNATTR_GETSIGDEFAULT",
    "GNULIB_POSIX_SPAWNATTR_GETSIGMASK",
    "GNULIB_POSIX_SPAWNATTR_INIT",
    "GNULIB_POSIX_SPAWNATTR_SETFLAGS",
    "GNULIB_POSIX_SPAWNATTR_SETPGROUP",
    "GNULIB_POSIX_SPAWNATTR_SETSCHEDPARAM",
    "GNULIB_POSIX_SPAWNATTR_SETSCHEDPOLICY",
    "GNULIB_POSIX_SPAWNATTR_SETSIGDEFAULT",
    "GNULIB_POSIX_SPAWNATTR_SETSIGMASK",
    "GNULIB_POSIX_SPAWNP",
    "GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR",
    "GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDCLOSE",
    "GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDDUP2",
    "GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDFCHDIR",
    "GNULIB_POSIX_SPAWN_FILE_ACTIONS_ADDOPEN",
    "GNULIB_POSIX_SPAWN_FILE_ACTIONS_DESTROY",
    "GNULIB_POSIX_SPAWN_FILE_ACTIONS_INIT",
    "GNULIB_POWF",
    "GNULIB_PREAD",
    "GNULIB_PRINTF",
    "GNULIB_PRINTF_POSIX",
    "GNULIB_PTHREAD_SIGMASK",
    "GNULIB_PTSNAME",
    "GNULIB_PTSNAME_R",
    "GNULIB_PUTC",
    "GNULIB_PUTCHAR",
    "GNULIB_PUTENV",
    "GNULIB_PUTS",
    "GNULIB_PWRITE",
    "GNULIB_QSORT_R",
    "GNULIB_RAISE",
    "GNULIB_RANDOM",
    "GNULIB_RANDOM_R",
    "GNULIB_RAWMEMCHR",
    "GNULIB_READ",
    "GNULIB_READDIR",
    "GNULIB_READLINK",
    "GNULIB_READLINKAT",
    "GNULIB_REALLOCARRAY",
    "GNULIB_REALLOC_POSIX",
    "GNULIB_REALPATH",
    "GNULIB_REMAINDER",
    "GNULIB_REMAINDERF",
    "GNULIB_REMAINDERL",
    "GNULIB_REMOVE",
    "GNULIB_RENAME",
    "GNULIB_RENAMEAT",
    "GNULIB_REWINDDIR",
    "GNULIB_RINT",
    "GNULIB_RINTF",
    "GNULIB_RINTL",
    "GNULIB_RMDIR",
    "GNULIB_ROUND",
    "GNULIB_ROUNDF",
    "GNULIB_ROUNDL",
    "GNULIB_RPMATCH",
    "GNULIB_SCANDIR",
    "GNULIB_SCANF",
    "GNULIB_SCHED_YIELD",
    "GNULIB_SECURE_GETENV",
    "GNULIB_SETENV",
    "GNULIB_SETHOSTNAME",
    "GNULIB_SETLOCALE",
    "GNULIB_SETLOCALE_NULL",
    "GNULIB_SIGABBREV_NP",
    "GNULIB_SIGACTION",
    "GNULIB_SIGDESCR_NP",
    "GNULIB_SIGNAL_H_SIGPIPE",
    "GNULIB_SIGNBIT",
    "GNULIB_SIGPROCMASK",
    "GNULIB_SINF",
    "GNULIB_SINHF",
    "GNULIB_SINL",
    "GNULIB_SLEEP",
    "GNULIB_SNPRINTF",
    "GNULIB_SPRINTF_POSIX",
    "GNULIB_SQRTF",
    "GNULIB_SQRTL",
    "GNULIB_STAT",
    "GNULIB_STDIO_H_NONBLOCKING",
    "GNULIB_STDIO_H_SIGPIPE",
    "GNULIB_STPCPY",
    "GNULIB_STPNCPY",
    "GNULIB_STRCASESTR",
    "GNULIB_STRCHRNUL",
    "GNULIB_STRDUP",
    "GNULIB_STRERROR",
    "GNULIB_STRERRORNAME_NP",
    "GNULIB_STRERROR_R",
    "GNULIB_STRFTIME",
    "GNULIB_STRNCAT",
    "GNULIB_STRNDUP",
    "GNULIB_STRNLEN",
    "GNULIB_STRPBRK",
    "GNULIB_STRPTIME",
    "GNULIB_STRSEP",
    "GNULIB_STRSIGNAL",
    "GNULIB_STRSTR",
    "GNULIB_STRTOD",
    "GNULIB_STRTOIMAX",
    "GNULIB_STRTOK_R",
    "GNULIB_STRTOL",
    "GNULIB_STRTOLD",
    "GNULIB_STRTOLL",
    "GNULIB_STRTOUL",
    "GNULIB_STRTOULL",
    "GNULIB_STRTOUMAX",
    "GNULIB_STRVERSCMP",
    "GNULIB_SYMLINK",
    "GNULIB_SYMLINKAT",
    "GNULIB_SYSTEM_POSIX",
    "GNULIB_TANF",
    "GNULIB_TANHF",
    "GNULIB_TANL",
    "GNULIB_TCGETSID",
    "GNULIB_TIMEGM",
    "GNULIB_TIMES",
    "GNULIB_TIMESPEC_GET",
    "GNULIB_TIME_R",
    "GNULIB_TIME_RZ",
    "GNULIB_TMPFILE",
    "GNULIB_TOWCTRANS",
    "GNULIB_TRUNC",
    "GNULIB_TRUNCATE",
    "GNULIB_TRUNCF",
    "GNULIB_TRUNCL",
    "GNULIB_TTYNAME_R",
    "GNULIB_TZSET",
    "GNULIB_UNISTD_H_GETOPT",
    "GNULIB_UNLINK",
    "GNULIB_UNLINKAT",
    "GNULIB_UNLOCKPT",
    "GNULIB_UNSETENV",
    "GNULIB_USLEEP",
    "GNULIB_UTIMENSAT",
    "GNULIB_VASPRINTF",
    "GNULIB_VDPRINTF",
    "GNULIB_VFPRINTF",
    "GNULIB_VFPRINTF_POSIX",
    "GNULIB_VFSCANF",
    "GNULIB_VPRINTF",
    "GNULIB_VPRINTF_POSIX",
    "GNULIB_VSCANF",
    "GNULIB_VSNPRINTF",
    "GNULIB_VSPRINTF_POSIX",
    "GNULIB_WAITPID",
    "GNULIB_WCPCPY",
    "GNULIB_WCPNCPY",
    "GNULIB_WCRTOMB",
    "GNULIB_WCSCASECMP",
    "GNULIB_WCSCAT",
    "GNULIB_WCSCHR",
    "GNULIB_WCSCMP",
    "GNULIB_WCSCOLL",
    "GNULIB_WCSCPY",
    "GNULIB_WCSCSPN",
    "GNULIB_WCSDUP",
    "GNULIB_WCSFTIME",
    "GNULIB_WCSLEN",
    "GNULIB_WCSNCASECMP",
    "GNULIB_WCSNCAT",
    "GNULIB_WCSNCMP",
    "GNULIB_WCSNCPY",
    "GNULIB_WCSNLEN",
    "GNULIB_WCSNRTOMBS",
    "GNULIB_WCSPBRK",
    "GNULIB_WCSRCHR",
    "GNULIB_WCSRTOMBS",
    "GNULIB_WCSSPN",
    "GNULIB_WCSSTR",
    "GNULIB_WCSTOK",
    "GNULIB_WCSWIDTH",
    "GNULIB_WCSXFRM",
    "GNULIB_WCTOB",
    "GNULIB_WCTOMB",
    "GNULIB_WCTRANS",
    "GNULIB_WCTYPE",
    "GNULIB_WCWIDTH",
    "GNULIB_WMEMCHR",
    "GNULIB_WMEMCMP",
    "GNULIB_WMEMCPY",
    "GNULIB_WMEMMOVE",
    "GNULIB_WMEMPCPY",
    "GNULIB_WMEMSET",
    "GNULIB_WRITE",
    "GNULIB__EXIT",
    "GUARD_PREFIX",
    "HAVE_ACOSF",
    "HAVE_ACOSL",
    "HAVE_ALIGNED_ALLOC",
    "HAVE_ALLOCA_H",
    "HAVE_ALPHASORT",
    "HAVE_ASINF",
    "HAVE_ASINL",
    "HAVE_ATAN2F",
    "HAVE_ATANF",
    "HAVE_ATANL",
    "HAVE_ATOLL",
    "HAVE_BTOWC",
    "HAVE_C99_STDINT_H",
    "HAVE_CANONICALIZE_FILE_NAME",
    "HAVE_CBRT",
    "HAVE_CHOWN",
    "HAVE_CLOSEDIR",
    "HAVE_COPYSIGN",
    "HAVE_COPYSIGNL",
    "HAVE_COPY_FILE_RANGE",
    "HAVE_COSF",
    "HAVE_COSHF",
    "HAVE_COSL",
    "HAVE_CRTDEFS_H",
    "HAVE_DECL_ACOSL",
    "HAVE_DECL_ASINL",
    "HAVE_DECL_ATANL",
    "HAVE_DECL_CBRTF",
    "HAVE_DECL_CBRTL",
    "HAVE_DECL_CEILF",
    "HAVE_DECL_CEILL",
    "HAVE_DECL_COPYSIGNF",
    "HAVE_DECL_COSL",
    "HAVE_DECL_DIRFD",
    "HAVE_DECL_ECVT",
    "HAVE_DECL_ENVIRON",
    "HAVE_DECL_EXECVPE",
    "HAVE_DECL_EXP2",
    "HAVE_DECL_EXP2F",
    "HAVE_DECL_EXP2L",
    "HAVE_DECL_EXPL",
    "HAVE_DECL_EXPM1L",
    "HAVE_DECL_FCHDIR",
    "HAVE_DECL_FCLOSEALL",
    "HAVE_DECL_FCVT",
    "HAVE_DECL_FDATASYNC",
    "HAVE_DECL_FDOPENDIR",
    "HAVE_DECL_FLOORF",
    "HAVE_DECL_FLOORL",
    "HAVE_DECL_FPURGE",
    "HAVE_DECL_FREXPL",
    "HAVE_DECL_FSEEKO",
    "HAVE_DECL_FTELLO",
    "HAVE_DECL_GCVT",
    "HAVE_DECL_GETDELIM",
    "HAVE_DECL_GETDOMAINNAME",
    "HAVE_DECL_GETLINE",
    "HAVE_DECL_GETLOADAVG",
    "HAVE_DECL_GETLOGIN",
    "HAVE_DECL_GETLOGIN_R",
    "HAVE_DECL_GETPAGESIZE",
    "HAVE_DECL_GETUSERSHELL",
    "HAVE_DECL_IMAXABS",
    "HAVE_DECL_IMAXDIV",
    "HAVE_DECL_INITSTATE",
    "HAVE_DECL_LDEXPL",
    "HAVE_DECL_LOCALTIME_R",
    "HAVE_DECL_LOG10L",
    "HAVE_DECL_LOG2",
    "HAVE_DECL_LOG2F",
    "HAVE_DECL_LOG2L",
    "HAVE_DECL_LOGB",
    "HAVE_DECL_LOGL",
    "HAVE_DECL_MEMMEM",
    "HAVE_DECL_MEMRCHR",
    "HAVE_DECL_OBSTACK_PRINTF",
    "HAVE_DECL_REMAINDER",
    "HAVE_DECL_REMAINDERL",
    "HAVE_DECL_RINTF",
    "HAVE_DECL_ROUND",
    "HAVE_DECL_ROUNDF",
    "HAVE_DECL_ROUNDL",
    "HAVE_DECL_SETENV",
    "HAVE_DECL_SETHOSTNAME",
    "HAVE_DECL_SETSTATE",
    "HAVE_DECL_SINL",
    "HAVE_DECL_SNPRINTF",
    "HAVE_DECL_SQRTL",
    "HAVE_DECL_STRDUP",
    "HAVE_DECL_STRERROR_R",
    "HAVE_DECL_STRNCASECMP",
    "HAVE_DECL_STRNDUP",
    "HAVE_DECL_STRNLEN",
    "HAVE_DECL_STRSIGNAL",
    "HAVE_DECL_STRTOIMAX",
    "HAVE_DECL_STRTOK_R",
    "HAVE_DECL_STRTOUMAX",
    "HAVE_DECL_TANL",
    "HAVE_DECL_TCGETSID",
    "HAVE_DECL_TRUNC",
    "HAVE_DECL_TRUNCATE",
    "HAVE_DECL_TRUNCF",
    "HAVE_DECL_TRUNCL",
    "HAVE_DECL_TTYNAME_R",
    "HAVE_DECL_UNSETENV",
    "HAVE_DECL_VSNPRINTF",
    "HAVE_DECL_WCSDUP",
    "HAVE_DECL_WCTOB",
    "HAVE_DECL_WCWIDTH",
    "HAVE_DIRENT_H",
    "HAVE_DPRINTF",
    "HAVE_DUP3",
    "HAVE_DUPLOCALE",
    "HAVE_EUIDACCESS",
    "HAVE_EXECVPE",
    "HAVE_EXPF",
    "HAVE_EXPL",
    "HAVE_EXPLICIT_BZERO",
    "HAVE_EXPM1",
    "HAVE_EXPM1F",
    "HAVE_FABSF",
    "HAVE_FABSL",
    "HAVE_FACCESSAT",
    "HAVE_FCHDIR",
    "HAVE_FCHMODAT",
    "HAVE_FCHOWNAT",
    "HAVE_FCNTL",
    "HAVE_FDATASYNC",
    "HAVE_FDOPENDIR",
    "HAVE_FEATURES_H",
    "HAVE_FFS",
    "HAVE_FFSL",
    "HAVE_FFSLL",
    "HAVE_FMA",
    "HAVE_FMAF",
    "HAVE_FMAL",
    "HAVE_FMODF",
    "HAVE_FMODL",
    "HAVE_FREELOCALE",
    "HAVE_FREXPF",
    "HAVE_FSTATAT",
    "HAVE_FSYNC",
    "HAVE_FTRUNCATE",
    "HAVE_FUTIMENS",
    "HAVE_GETDTABLESIZE",
    "HAVE_GETENTROPY",
    "HAVE_GETGROUPS",
    "HAVE_GETHOSTNAME",
    "HAVE_GETOPT_H",
    "HAVE_GETPAGESIZE",
    "HAVE_GETPASS",
    "HAVE_GETRUSAGE",
    "HAVE_GETSUBOPT",
    "HAVE_GETTIMEOFDAY",
    "HAVE_GETUMASK",
    "HAVE_GRANTPT",
    "HAVE_GROUP_MEMBER",
    "HAVE_HYPOTF",
    "HAVE_HYPOTL",
    "HAVE_ILOGB",
    "HAVE_ILOGBF",
    "HAVE_ILOGBL",
    "HAVE_IMAXDIV_T",
    "HAVE_INITSTATE",
    "HAVE_INTTYPES_H",
    "HAVE_ISNAND",
    "HAVE_ISNANF",
    "HAVE_ISNANL",
    "HAVE_ISWBLANK",
    "HAVE_ISWCNTRL",
    "HAVE_LCHMOD",
    "HAVE_LCHOWN",
    "HAVE_LDEXPF",
    "HAVE_LINK",
    "HAVE_LINKAT",
    "HAVE_LOG10F",
    "HAVE_LOG10L",
    "HAVE_LOG1P",
    "HAVE_LOG1PF",
    "HAVE_LOG1PL",
    "HAVE_LOGBF",
    "HAVE_LOGBL",
    "HAVE_LOGF",
    "HAVE_LOGL",
    "HAVE_LSTAT",
    "HAVE_MAX_ALIGN_T",
    "HAVE_MBRLEN",
    "HAVE_MBRTOWC",
    "HAVE_MBSINIT",
    "HAVE_MBSLEN",
    "HAVE_MBSNRTOWCS",
    "HAVE_MBSRTOWCS",
    "HAVE_MBTOWC",
    "HAVE_MEMPCPY",
    "HAVE_MKDIRAT",
    "HAVE_MKDTEMP",
    "HAVE_MKFIFO",
    "HAVE_MKFIFOAT",
    "HAVE_MKNOD",
    "HAVE_MKNODAT",
    "HAVE_MKOSTEMP",
    "HAVE_MKOSTEMPS",
    "HAVE_MKSTEMP",
    "HAVE_MKSTEMPS",
    "HAVE_MODFF",
    "HAVE_MODFL",
    "HAVE_NANOSLEEP",
    "HAVE_NEWLOCALE",
    "HAVE_OPENAT",
    "HAVE_OPENDIR",
    "HAVE_OS_H",
    "HAVE_PCLOSE",
    "HAVE_PIPE2",
    "HAVE_PIPE",
    "HAVE_POPEN",
    "HAVE_POSIX_MEMALIGN",
    "HAVE_POSIX_OPENPT",
    "HAVE_POSIX_SIGNALBLOCKING",
    "HAVE_POSIX_SPAWN",
    "HAVE_POSIX_SPAWNATTR_T",
    "HAVE_POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR",
    "HAVE_POSIX_SPAWN_FILE_ACTIONS_ADDFCHDIR",
    "HAVE_POSIX_SPAWN_FILE_ACTIONS_T",
    "HAVE_POWF",
    "HAVE_PREAD",
    "HAVE_PTHREAD_SIGMASK",
    "HAVE_PTSNAME",
    "HAVE_PTSNAME_R",
    "HAVE_PWRITE",
    "HAVE_QSORT_R",
    "HAVE_RAISE",
    "HAVE_RANDOM",
    "HAVE_RANDOM_H",
    "HAVE_RANDOM_R",
    "HAVE_RAWMEMCHR",
    "HAVE_READDIR",
    "HAVE_READLINK",
    "HAVE_READLINKAT",
    "HAVE_REALLOCARRAY",
    "HAVE_REALPATH",
    "HAVE_REMAINDER",
    "HAVE_REMAINDERF",
    "HAVE_RENAMEAT",
    "HAVE_REWINDDIR",
    "HAVE_RINT",
    "HAVE_RINTL",
    "HAVE_RPMATCH",
    "HAVE_SCANDIR",
    "HAVE_SCHED_H",
    "HAVE_SCHED_YIELD",
    "HAVE_SECURE_GETENV",
    "HAVE_SETHOSTNAME",
    "HAVE_SETSTATE",
    "HAVE_SIGABBREV_NP",
    "HAVE_SIGACTION",
    "HAVE_SIGDESCR_NP",
    "HAVE_SIGHANDLER_T",
    "HAVE_SIGINFO_T",
    "HAVE_SIGNED_SIG_ATOMIC_T",
    "HAVE_SIGNED_WCHAR_T",
    "HAVE_SIGNED_WINT_T",
    "HAVE_SIGSET_T",
    "HAVE_SINF",
    "HAVE_SINHF",
    "HAVE_SINL",
    "HAVE_SLEEP",
    "HAVE_SPAWN_H",
    "HAVE_SQRTF",
    "HAVE_SQRTL",
    "HAVE_STDINT_H",
    "HAVE_STPCPY",
    "HAVE_STPNCPY",
    "HAVE_STRCASECMP",
    "HAVE_STRCASESTR",
    "HAVE_STRCHRNUL",
    "HAVE_STRERRORNAME_NP",
    "HAVE_STRINGS_H",
    "HAVE_STRPBRK",
    "HAVE_STRPTIME",
    "HAVE_STRSEP",
    "HAVE_STRTOD",
    "HAVE_STRTOL",
    "HAVE_STRTOLD",
    "HAVE_STRTOLL",
    "HAVE_STRTOUL",
    "HAVE_STRTOULL",
    "HAVE_STRUCT_RANDOM_DATA",
    "HAVE_STRUCT_SCHED_PARAM",
    "HAVE_STRUCT_SIGACTION_SA_SIGACTION",
    "HAVE_STRUCT_TIMEVAL",
    "HAVE_STRUCT_TMS",
    "HAVE_STRVERSCMP",
    "HAVE_SYMLINK",
    "HAVE_SYMLINKAT",
    "HAVE_SYS_BITYPES_H",
    "HAVE_SYS_CDEFS_H",
    "HAVE_SYS_INTTYPES_H",
    "HAVE_SYS_IOCTL_H",
    "HAVE_SYS_LOADAVG_H",
    "HAVE_SYS_PARAM_H",
    "HAVE_SYS_RESOURCE_H",
    "HAVE_SYS_TIMES_H",
    "HAVE_SYS_TIME_H",
    "HAVE_SYS_TYPES_H",
    "HAVE_TANF",
    "HAVE_TANHF",
    "HAVE_TANL",
    "HAVE_TERMIOS_H",
    "HAVE_TIMEGM",
    "HAVE_TIMES",
    "HAVE_TIMESPEC_GET",
    "HAVE_TIMEZONE_T",
    "HAVE_TYPE_VOLATILE_SIG_ATOMIC_T",
    "HAVE_UNISTD_H",
    "HAVE_UNLINKAT",
    "HAVE_UNLOCKPT",
    "HAVE_USLEEP",
    "HAVE_UTIMENSAT",
    "HAVE_VASPRINTF",
    "HAVE_VDPRINTF",
    "HAVE_WCHAR_H",
    "HAVE_WCHAR_T",
    "HAVE_WCPCPY",
    "HAVE_WCPNCPY",
    "HAVE_WCRTOMB",
    "HAVE_WCSCASECMP",
    "HAVE_WCSCAT",
    "HAVE_WCSCHR",
    "HAVE_WCSCMP",
    "HAVE_WCSCOLL",
    "HAVE_WCSCPY",
    "HAVE_WCSCSPN",
    "HAVE_WCSDUP",
    "HAVE_WCSFTIME",
    "HAVE_WCSLEN",
    "HAVE_WCSNCASECMP",
    "HAVE_WCSNCAT",
    "HAVE_WCSNCMP",
    "HAVE_WCSNCPY",
    "HAVE_WCSNLEN",
    "HAVE_WCSNRTOMBS",
    "HAVE_WCSPBRK",
    "HAVE_WCSRCHR",
    "HAVE_WCSRTOMBS",
    "HAVE_WCSSPN",
    "HAVE_WCSSTR",
    "HAVE_WCSTOK",
    "HAVE_WCSWIDTH",
    "HAVE_WCSXFRM",
    "HAVE_WCTRANS_T",
    "HAVE_WCTYPE_H",
    "HAVE_WCTYPE_T",
    "HAVE_WINSOCK2_H",
    "HAVE_WINT_T",
    "HAVE_WMEMCHR",
    "HAVE_WMEMCMP",
    "HAVE_WMEMCPY",
    "HAVE_WMEMMOVE",
    "HAVE_WMEMPCPY",
    "HAVE_WMEMSET",
    "HAVE_XLOCALE_H",
    "HAVE__BOOL",
    "HAVE__EXIT",
    "ICONV_CONST",
    "INCLUDE_NEXT",
    "INCLUDE_NEXT_AS_FIRST_DIRECTIVE",
    "INT32_MAX_LT_INTMAX_MAX",
    "INT64_MAX_EQ_LONG_MAX",
    "LOCALENAME_ENHANCE_LOCALE_FUNCS",
    "NEXT_AS_FIRST_DIRECTIVE_MATH_H",
    "NEXT_DIRENT_H",
    "NEXT_ERRNO_H",
    "NEXT_FCNTL_H",
    "NEXT_FLOAT_H",
    "NEXT_GETOPT_H",
    "NEXT_ICONV_H",
    "NEXT_INTTYPES_H",
    "NEXT_LIMITS_H",
    "NEXT_LOCALE_H",
    "NEXT_SCHED_H",
    "NEXT_SIGNAL_H",
    "NEXT_SPAWN_H",
    "NEXT_STDDEF_H",
    "NEXT_STDINT_H",
    "NEXT_STDIO_H",
    "NEXT_STDLIB_H",
    "NEXT_STRINGS_H",
    "NEXT_STRING_H",
    "NEXT_SYS_IOCTL_H",
    "NEXT_SYS_RESOURCE_H",
    "NEXT_SYS_STAT_H",
    "NEXT_SYS_TIMES_H",
    "NEXT_SYS_TIME_H",
    "NEXT_SYS_TYPES_H",
    "NEXT_SYS_WAIT_H",
    "NEXT_TERMIOS_H",
    "NEXT_TIME_H",
    "NEXT_UNISTD_H",
    "NEXT_WCHAR_H",
    "NEXT_WCTYPE_H",
    "PRAGMA_COLUMNS",
    "PRAGMA_SYSTEM_HEADER",
    "PRIPTR_PREFIX",
    "PTHREAD_H_DEFINES_STRUCT_TIMESPEC",
    "PTRDIFF_T_SUFFIX",
    "REPLACE_ACCESS",
    "REPLACE_ACOSF",
    "REPLACE_ALIGNED_ALLOC",
    "REPLACE_ASINF",
    "REPLACE_ATAN2F",
    "REPLACE_ATANF",
    "REPLACE_BTOWC",
    "REPLACE_CALLOC",
    "REPLACE_CANONICALIZE_FILE_NAME",
    "REPLACE_CBRTF",
    "REPLACE_CBRTL",
    "REPLACE_CEIL",
    "REPLACE_CEILF",
    "REPLACE_CEILL",
    "REPLACE_CHOWN",
    "REPLACE_CLOSE",
    "REPLACE_CLOSEDIR",
    "REPLACE_COSF",
    "REPLACE_COSHF",
    "REPLACE_CREAT",
    "REPLACE_CTIME",
    "REPLACE_DIRFD",
    "REPLACE_DPRINTF",
    "REPLACE_DUP2",
    "REPLACE_DUP",
    "REPLACE_DUPLOCALE",
    "REPLACE_EXECL",
    "REPLACE_EXECLE",
    "REPLACE_EXECLP",
    "REPLACE_EXECV",
    "REPLACE_EXECVE",
    "REPLACE_EXECVP",
    "REPLACE_EXECVPE",
    "REPLACE_EXP2",
    "REPLACE_EXP2L",
    "REPLACE_EXPF",
    "REPLACE_EXPL",
    "REPLACE_EXPM1",
    "REPLACE_EXPM1F",
    "REPLACE_EXPM1L",
    "REPLACE_FABSL",
    "REPLACE_FACCESSAT",
    "REPLACE_FCHMODAT",
    "REPLACE_FCHOWNAT",
    "REPLACE_FCLOSE",
    "REPLACE_FCNTL",
    "REPLACE_FDOPEN",
    "REPLACE_FDOPENDIR",
    "REPLACE_FFLUSH",
    "REPLACE_FFSLL",
    "REPLACE_FLOOR",
    "REPLACE_FLOORF",
    "REPLACE_FLOORL",
    "REPLACE_FMA",
    "REPLACE_FMAF",
    "REPLACE_FMAL",
    "REPLACE_FMOD",
    "REPLACE_FMODF",
    "REPLACE_FMODL",
    "REPLACE_FOPEN",
    "REPLACE_FPRINTF",
    "REPLACE_FPURGE",
    "REPLACE_FREE",
    "REPLACE_FREELOCALE",
    "REPLACE_FREOPEN",
    "REPLACE_FREXP",
    "REPLACE_FREXPF",
    "REPLACE_FREXPL",
    "REPLACE_FSEEK",
    "REPLACE_FSEEKO",
    "REPLACE_FSTAT",
    "REPLACE_FSTATAT",
    "REPLACE_FTELL",
    "REPLACE_FTELLO",
    "REPLACE_FTRUNCATE",
    "REPLACE_FUTIMENS",
    "REPLACE_GETCWD",
    "REPLACE_GETDELIM",
    "REPLACE_GETDOMAINNAME",
    "REPLACE_GETDTABLESIZE",
    "REPLACE_GETGROUPS",
    "REPLACE_GETLINE",
    "REPLACE_GETLOGIN_R",
    "REPLACE_GETPAGESIZE",
    "REPLACE_GETPASS",
    "REPLACE_GETTIMEOFDAY",
    "REPLACE_GMTIME",
    "REPLACE_HUGE_VAL",
    "REPLACE_HYPOT",
    "REPLACE_HYPOTF",
    "REPLACE_HYPOTL",
    "REPLACE_ICONV",
    "REPLACE_ICONV_OPEN",
    "REPLACE_ICONV_UTF",
    "REPLACE_ILOGB",
    "REPLACE_ILOGBF",
    "REPLACE_ILOGBL",
    "REPLACE_INITSTATE",
    "REPLACE_IOCTL",
    "REPLACE_ISATTY",
    "REPLACE_ISFINITE",
    "REPLACE_ISINF",
    "REPLACE_ISNAN",
    "REPLACE_ISWBLANK",
    "REPLACE_ISWCNTRL",
    "REPLACE_ISWDIGIT",
    "REPLACE_ISWXDIGIT",
    "REPLACE_ITOLD",
    "REPLACE_LCHOWN",
    "REPLACE_LDEXPL",
    "REPLACE_LINK",
    "REPLACE_LINKAT",
    "REPLACE_LOCALECONV",
    "REPLACE_LOCALTIME",
    "REPLACE_LOCALTIME_R",
    "REPLACE_LOG10",
    "REPLACE_LOG10F",
    "REPLACE_LOG10L",
    "REPLACE_LOG1P",
    "REPLACE_LOG1PF",
    "REPLACE_LOG1PL",
    "REPLACE_LOG2",
    "REPLACE_LOG2F",
    "REPLACE_LOG2L",
    "REPLACE_LOG",
    "REPLACE_LOGB",
    "REPLACE_LOGBF",
    "REPLACE_LOGBL",
    "REPLACE_LOGF",
    "REPLACE_LOGL",
    "REPLACE_LSEEK",
    "REPLACE_LSTAT",
    "REPLACE_MALLOC",
    "REPLACE_MBRLEN",
    "REPLACE_MBRTOWC",
    "REPLACE_MBSINIT",
    "REPLACE_MBSNRTOWCS",
    "REPLACE_MBSRTOWCS",
    "REPLACE_MBSTATE_T",
    "REPLACE_MBTOWC",
    "REPLACE_MEMCHR",
    "REPLACE_MEMMEM",
    "REPLACE_MKDIR",
    "REPLACE_MKFIFO",
    "REPLACE_MKFIFOAT",
    "REPLACE_MKNOD",
    "REPLACE_MKNODAT",
    "REPLACE_MKSTEMP",
    "REPLACE_MKTIME",
    "REPLACE_MODF",
    "REPLACE_MODFF",
    "REPLACE_MODFL",
    "REPLACE_NAN",
    "REPLACE_NANOSLEEP",
    "REPLACE_NEWLOCALE",
    "REPLACE_NULL",
    "REPLACE_OBSTACK_PRINTF",
    "REPLACE_OPEN",
    "REPLACE_OPENAT",
    "REPLACE_OPENDIR",
    "REPLACE_PERROR",
    "REPLACE_POPEN",
    "REPLACE_POSIX_MEMALIGN",
    "REPLACE_POSIX_SPAWN",
    "REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDCHDIR",
    "REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDCLOSE",
    "REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDDUP2",
    "REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDFCHDIR",
    "REPLACE_POSIX_SPAWN_FILE_ACTIONS_ADDOPEN",
    "REPLACE_PREAD",
    "REPLACE_PRINTF",
    "REPLACE_PTHREAD_SIGMASK",
    "REPLACE_PTSNAME",
    "REPLACE_PTSNAME_R",
    "REPLACE_PUTENV",
    "REPLACE_PWRITE",
    "REPLACE_QSORT_R",
    "REPLACE_RAISE",
    "REPLACE_RANDOM",
    "REPLACE_RANDOM_R",
    "REPLACE_READ",
    "REPLACE_READLINK",
    "REPLACE_READLINKAT",
    "REPLACE_REALLOC",
    "REPLACE_REALLOCARRAY",
    "REPLACE_REALPATH",
    "REPLACE_REMAINDER",
    "REPLACE_REMAINDERF",
    "REPLACE_REMAINDERL",
    "REPLACE_REMOVE",
    "REPLACE_RENAME",
    "REPLACE_RENAMEAT",
    "REPLACE_RINTL",
    "REPLACE_RMDIR",
    "REPLACE_ROUND",
    "REPLACE_ROUNDF",
    "REPLACE_ROUNDL",
    "REPLACE_SCHED_YIELD",
    "REPLACE_SETENV",
    "REPLACE_SETLOCALE",
    "REPLACE_SETSTATE",
    "REPLACE_SIGNBIT",
    "REPLACE_SIGNBIT_USING_BUILTINS",
    "REPLACE_SINF",
    "REPLACE_SINHF",
    "REPLACE_SLEEP",
    "REPLACE_SNPRINTF",
    "REPLACE_SPRINTF",
    "REPLACE_SQRTF",
    "REPLACE_SQRTL",
    "REPLACE_STAT",
    "REPLACE_STDIO_READ_FUNCS",
    "REPLACE_STDIO_WRITE_FUNCS",
    "REPLACE_STPNCPY",
    "REPLACE_STRCASESTR",
    "REPLACE_STRCHRNUL",
    "REPLACE_STRDUP",
    "REPLACE_STRERROR",
    "REPLACE_STRERRORNAME_NP",
    "REPLACE_STRERROR_R",
    "REPLACE_STRFTIME",
    "REPLACE_STRNCAT",
    "REPLACE_STRNDUP",
    "REPLACE_STRNLEN",
    "REPLACE_STRSIGNAL",
    "REPLACE_STRSTR",
    "REPLACE_STRTOD",
    "REPLACE_STRTOIMAX",
    "REPLACE_STRTOK_R",
    "REPLACE_STRTOL",
    "REPLACE_STRTOLD",
    "REPLACE_STRTOLL",
    "REPLACE_STRTOUL",
    "REPLACE_STRTOULL",
    "REPLACE_STRTOUMAX",
    "REPLACE_STRUCT_LCONV",
    "REPLACE_STRUCT_TIMEVAL",
    "REPLACE_SYMLINK",
    "REPLACE_SYMLINKAT",
    "REPLACE_TANF",
    "REPLACE_TANHF",
    "REPLACE_TIMEGM",
    "REPLACE_TMPFILE",
    "REPLACE_TOWLOWER",
    "REPLACE_TRUNC",
    "REPLACE_TRUNCATE",
    "REPLACE_TRUNCF",
    "REPLACE_TRUNCL",
    "REPLACE_TTYNAME_R",
    "REPLACE_TZSET",
    "REPLACE_UNLINK",
    "REPLACE_UNLINKAT",
    "REPLACE_UNSETENV",
    "REPLACE_USLEEP",
    "REPLACE_UTIMENSAT",
    "REPLACE_VASPRINTF",
    "REPLACE_VDPRINTF",
    "REPLACE_VFPRINTF",
    "REPLACE_VPRINTF",
    "REPLACE_VSNPRINTF",
    "REPLACE_VSPRINTF",
    "REPLACE_WCRTOMB",
    "REPLACE_WCSFTIME",
    "REPLACE_WCSNRTOMBS",
    "REPLACE_WCSRTOMBS",
    "REPLACE_WCSTOK",
    "REPLACE_WCSWIDTH",
    "REPLACE_WCTOB",
    "REPLACE_WCTOMB",
    "REPLACE_WCWIDTH",
    "REPLACE_WRITE",
    "SIG_ATOMIC_T_SUFFIX",
    "SIZE_T_SUFFIX",
    "SYS_IOCTL_H_HAVE_WINSOCK2_H",
    "SYS_IOCTL_H_HAVE_WINSOCK2_H_AND_USE_SOCKETS",
    "SYS_TIME_H_DEFINES_STRUCT_TIMESPEC",
    "TIME_H_DEFINES_STRUCT_TIMESPEC",
    "TIME_H_DEFINES_TIME_UTC",
    "UINT32_MAX_LT_UINTMAX_MAX",
    "UINT64_MAX_EQ_ULONG_MAX",
    "UNDEFINE_STRTOK_R",
    "UNISTD_H_DEFINES_STRUCT_TIMESPEC",
    "UNISTD_H_HAVE_SYS_RANDOM_H",
    "UNISTD_H_HAVE_WINSOCK2_H",
    "UNISTD_H_HAVE_WINSOCK2_H_AND_USE_SOCKETS",
    "WCHAR_T_SUFFIX",
    "WINDOWS_64_BIT_OFF_T",
    "WINDOWS_64_BIT_ST_SIZE",
    "WINDOWS_STAT_INODES",
    "WINDOWS_STAT_TIMESPEC",
    "WINT_T_SUFFIX",
]

FILE_REPLACEMENT_KEYS = [
    "definition of _GL_ARG_NONNULL",
    "definition of _GL_WARN_ON_USE",
    "definition of _GL_WARN_ON_USE",
    "definition of _Noreturn",
    "definitions of _GL_FUNCDECL_RPL",
]

DIRECT_REPLACEMENT_KEYS = [
    "__always_inline",
    "__glibc_likely",
    "__glibc_unlikely",
]

DELETE_KEYS = [
    "libc_hidden_proto",
]

_BZL_TEMPLATE = """\
\"\"\"Configuration values\"\"\"

AUTOMAKE_VARIABLES = {}

DIRECT_VARIABLES = {}

INLINE_VARIABLES = {}

DELETE_VARIABLES = {}
"""


def parse_args() -> argparse.Namespace:
    """Parse command line arguments."""
    parser = argparse.ArgumentParser()

    parser.add_argument(
        "version",
        type=str,
        help="The version of bison to process.",
    )

    parser.add_argument(
        "checkout",
        type=Path,
        help="The location of a fully built bison checkout",
    )

    default_platform = "linux"
    if platform.system() == "Darwin":
        default_platform = "macos"
    elif platform.system() == "Windows":
        default_platform = "windows"

    parser.add_argument(
        "--platform",
        type=str,
        default=default_platform,
        choices=[
            "macos",
            "linux",
            "windows",
        ],
        help="The platform to process.",
    )

    return parser.parse_args()


def get_module_bison_path(version: str) -> Path:
    """Locate the bison module path."""
    if "BUILD_WORKSPACE_DIRECTORY" in os.environ:
        return Path(os.environ["BUILD_WORKSPACE_DIRECTORY"]) / f"modules/bison/{version}"

    return Path(__file__).parent / version


def collect_template_values(
    makefile: Path,
) -> tuple[dict[str, str], dict[str, str], dict[str, str], list[str]]:
    """Collect template values from the Makefile generated in the Bison checkout."""
    content = makefile.read_text(encoding="utf-8")

    sed_mappings = {}
    # Look for sed commands like: -e 's/@''GNULIB_FMODF''@/$(GL_GNULIB_FMODF)/g'
    sed_pattern = re.compile(r"-e\s+'s/@''([A-Z_][\w\d_]*)''@/0?\$\(([\w\d_]+)\)/g'")
    for key, value in sed_pattern.findall(content):
        sed_mappings[key] = value

    defines = {}
    # Look for Makefile defines like: `FOO = 1`
    defines_pattern = re.compile(r"^([\w_-]+) = (.*)$", re.MULTILINE)
    for key, value in defines_pattern.findall(content):
        defines[key] = value

    automake_templates = {}
    for key in sorted(TEMPLATE_KEYS):
        real_key = sed_mappings.get(key, key)
        sed_key = f"@''{key}''@"
        automake_templates[sed_key] = defines.get(real_key, "")
        # This variable is weirdly prefixed with `0` so that should be
        # retained.
        if real_key == "GL_GNULIB_UNISTD_H_GETOPT":
            automake_templates[sed_key] = f"0{automake_templates[sed_key]}"

    direct_templates = {}
    direct_pattern = re.compile(r"-e\s+'s\|([\w_]+)\|([\w\s]+)\|g'", re.MULTILINE)
    for key, value in direct_pattern.findall(content):
        if key not in DIRECT_REPLACEMENT_KEYS:
            continue
        direct_templates[key] = value

    inlines = {}
    # Look for sed commands like:
    inline_pattern = re.compile(r"^\s+-e\s+'\/([\w\s_]+)\/r \$\(([\w_]+)\)'", re.MULTILINE)
    for key, value in inline_pattern.findall(content):
        inlines[key] = defines[value].replace("$(top_srcdir)/", "")

    inline_templates = {}
    for key in sorted(FILE_REPLACEMENT_KEYS):
        inline_templates[key] = inlines[key]

    delete_keys = []
    delete_pattern = re.compile(r"-e '/([\w_]+)/d'", re.MULTILINE)
    for key in delete_pattern.findall(content):
        if key not in sorted(DELETE_KEYS):
            continue
        delete_keys.append(key)

    return automake_templates, direct_templates, inline_templates, delete_keys


def main() -> None:
    """The main entrypoint."""
    args = parse_args()

    module_path = get_module_bison_path(args.version)

    checkout = Path(args.checkout)
    assert checkout.exists(), "Checkout directory doesn't exist."

    makefile = checkout / "Makefile"
    assert makefile.exists(), "Makefile didn't exist in checkout, was it configured?"

    config_src = checkout / "lib/config.h"
    assert config_src.exists(), "config.h didn't exist in checkout, was it compiled?"

    automake_vars, direct_vars, inline_vars, delete_keys = collect_template_values(makefile)

    config_bzl = module_path / f"overlay/config_{args.platform}.bzl"
    config_bzl.parent.mkdir(exist_ok=True, parents=True)
    config_bzl.write_text(
        _BZL_TEMPLATE.format(
            json.dumps(automake_vars, indent=4).replace("\n}", ",\n}"),
            json.dumps(direct_vars, indent=4).replace("\n}", ",\n}"),
            json.dumps(inline_vars, indent=4).replace("\n}", ",\n}"),
            json.dumps(delete_keys, indent=4).replace("\n]", ",\n]"),
        )
        + "\n"
    )
    config_h = module_path / f"overlay/config_{args.platform}.h"
    config_h.parent.mkdir(exist_ok=True, parents=True)
    shutil.copy2(config_src, config_h)


if __name__ == "__main__":
    main()
